Conversation
05.wc/wc.rb
Outdated
| display(totals, flags) | ||
| end | ||
|
|
||
| get_option_and_paths(ARGV) => { line:, word:, byte:, paths: } |
There was a problem hiding this comment.
82-100行目はmainメソッドに入れてみてください〜。
https://qiita.com/jnchito/items/4b4cae54170cc2f4377e
05.wc/wc.rb
Outdated
| else | ||
| paths.each do |path| | ||
| outputs = {} | ||
| if File.directory?(path) |
There was a problem hiding this comment.
ディレクトリのケースって、スクショ載せてます?
https://bootcamp.fjord.jp/pages/write-code-write-test
05.wc/wc.rb
Outdated
| { | ||
| line: File.read(path).lines.count, | ||
| word: File.read(path).split.count, | ||
| byte: File.size(path), |
There was a problem hiding this comment.
byte: input.sizeの結果と数値が変わりそうですね。
同じ入力値に対しては同じ出力値が出るようにしてほしいです。
05.wc/wc.rb
Outdated
| def build_file_output(path) | ||
| { | ||
| line: File.read(path).lines.count, | ||
| word: File.read(path).split.count, |
There was a problem hiding this comment.
読み取り対象のファイルが巨大な場合、readを繰り返すとメモリの消費や実行時間が増えてしまいそうです。
05.wc/wc.rb
Outdated
| byte: File.size(path), | ||
| name: path | ||
| } | ||
| rescue Errno::ENOTDIR |
05.wc/wc.rb
Outdated
|
|
||
| def display(outputs, flags) | ||
| # ループ処理にするとflagsとoutputsの要素の順番が同期する必要があるため、今後予期せぬバグに繋がると判断しこのように記述している。 | ||
| outputs.delete(:line) unless flags[:line] |
There was a problem hiding this comment.
引数を破壊的に変更するのは避けたいですね。
https://bootcamp.fjord.jp/pages/do-not-use-destructive-method
05.wc/wc.rb
Outdated
| def calculate_total(totals, outputs) | ||
| return totals if outputs.key?(:error) | ||
|
|
||
| totals[:line] += outputs[:line] |
05.wc/wc.rb
Outdated
| return str_output.rjust(width) if key == :line || :word || :byte | ||
|
|
||
| str_output.ljust(width) | ||
| def calculate_output_width(text_metadata_collection) |
There was a problem hiding this comment.
入力に応じて動的に幅を計算するメソッドを追加し、後ほどのadjust_styleと組み合わせて右揃えのレイアウトを実現しました
05.wc/wc.rb
Outdated
| end | ||
| display_totals(totals, output_flags) if paths.length > 1 | ||
| end | ||
| option_and_paths => { paths:, **option_flags } |
There was a problem hiding this comment.
パターンマッチの結果を分割代入し、output_flags = { line:, word:, byte: }で行われていた無駄な再定義を無くしました
05.wc/wc.rb
Outdated
| byte: input.size | ||
| } | ||
| def display(paths, option_flags) | ||
| text_metadata_collection = |
There was a problem hiding this comment.
元のstdins、outputsにあたるもの命名をtext_metadata_collectionとしました
|
|
||
| def build_directory_output(path) | ||
| def set_text_metadata(option_flags, message: nil, input: '', name: nil) | ||
| { |
There was a problem hiding this comment.
build_stdin_outputとbuild_file_outputの処理をset_text_metadataにて共通化しました
05.wc/wc.rb
Outdated
| } | ||
| def build_text_metadata(paths, option_flags) | ||
| text_metadata_collection = paths.map do |path| | ||
| if File.directory?(path) |
There was a problem hiding this comment.
例外処理で行っていたエラー処理をif文での実行に変えました
| opt.on('-w') { |v| word = v } | ||
| opt.on('-c') { |v| byte = v } | ||
| paths = opt.parse(arguments) | ||
| paths = opt.parse(ARGV) |
05.wc/wc.rb
Outdated
| temporary[key] = (temporary[key] || 0) + data if %i[line_count word_count size].include?(key) | ||
| end | ||
| end | ||
| totals.merge(name: 'total') |
05.wc/wc.rb
Outdated
| end | ||
| end | ||
| if text_metadata_collection.length > 1 | ||
| text_metadata_collection + [calculate_total(text_metadata_collection)] |
There was a problem hiding this comment.
破壊的変更を起こさないためにこのような記述になっています。
05.wc/wc.rb
Outdated
| if paths.empty? | ||
| [create_text_metadata(input: $stdin.read)] | ||
| else | ||
| build_text_metadata(paths) |
There was a problem hiding this comment.
create_text_metadataとbuild_text_metadata、名前だけ見ると、どちらも同じ機能を持つメソッドに見えますね。(createとbuildという動詞に大きな違いがない&目的語もtext_metadataで同じ)
実際は提供する機能(取得されるデータ)は異なるはずなので、もっと違いがわかる名前を付けたいなと思いました。
There was a problem hiding this comment.
命名を修正にて修正しました!
wcのWikipediaを参考にしました
https://en.wikipedia.org/wiki/Wc_(Unix)
05.wc/wc.rb
Outdated
| def main | ||
| option_and_paths => { paths:, **option_flags } | ||
| display(paths, option_flags) | ||
| paths, target_options = options_and_paths |
There was a problem hiding this comment.
options_and_pathsなら、その順番に合わせて
| paths, target_options = options_and_paths | |
| target_options, paths = options_and_paths |
にする方がいいかも。
あと、target_は省略してもいいんじゃないでしょうか。
05.wc/wc.rb
Outdated
| end | ||
| width = calculate_output_width(text_metadata_collection, target_options) | ||
| text_metadata_collection.each do |text_metadata| | ||
| render(target_options, text_metadata, width) |
There was a problem hiding this comment.
| render(target_options, text_metadata, width) | |
| render(text_metadata, target_options, width) |
text_metadataをrenderするのが主目的なので、text_metadataが最初の引数にある方がいいですね。
オプションの類いは引数の順番としては後ろの方に来ることが多いです。
There was a problem hiding this comment.
引数の順番にも意味があるのですね!ありがとうございます!
返り値や引数の順番を修正にて修正しました!
05.wc/wc.rb
Outdated
| { line_count: line, word_count: word, size: size }.map do |option, flag| | ||
| option if flag | ||
| end.compact |
There was a problem hiding this comment.
| { line_count: line, word_count: word, size: size }.map do |option, flag| | |
| option if flag | |
| end.compact | |
| { line_count: line, word_count: word, size: size }.select { |_, v| v }.keys |
こんな書き方もできます
There was a problem hiding this comment.
select、keysのメソッドは初めて使いました!短く記述できて好みでした( ´∀` )
冗長であったため修正にて反映しました!
05.wc/wc.rb
Outdated
| opt.on('-w') { |v| word = v } | ||
| opt.on('-c') { |v| size = v } | ||
| paths = opt.parse(ARGV) | ||
| target_options = |
There was a problem hiding this comment.
データの中身を考えるとオプションというより、出力対象の項目名、っていう感じがしますね 🤔
There was a problem hiding this comment.
命名を修正にて修正しました!
wcのWikipediaを参考にしました
https://en.wikipedia.org/wiki/Wc_(Unix)
05.wc/wc.rb
Outdated
| [paths, target_options] | ||
| end | ||
|
|
||
| def create_text_metadata(input:, name: nil) |
There was a problem hiding this comment.
| def create_text_metadata(input:, name: nil) | |
| def create_text_metadata(input, name = nil) |
キーワード引数じゃなくてもいいんじゃないかなー、と思います
https://bootcamp.fjord.jp/pages/dont-abuse-keyword-args
05.wc/wc.rb
Outdated
| if text_metadata_collection.length > 1 | ||
| text_metadata_collection + [calculate_total(text_metadata_collection)] | ||
| else | ||
| text_metadata_collection | ||
| end |
There was a problem hiding this comment.
| if text_metadata_collection.length > 1 | |
| text_metadata_collection + [calculate_total(text_metadata_collection)] | |
| else | |
| text_metadata_collection | |
| end | |
| text_metadata_collection << calculate_total(text_metadata_collection) if paths.size > 1 | |
| text_metadata_collection |
好みの問題ですが、こんなふうに書くのもありです
05.wc/wc.rb
Outdated
| target_options.each do |option| | ||
| print "#{text_metadata[option].to_s.rjust(width)} " | ||
| end | ||
| print text_metadata[:name] | ||
| puts '' |
There was a problem hiding this comment.
| target_options.each do |option| | |
| print "#{text_metadata[option].to_s.rjust(width)} " | |
| end | |
| print text_metadata[:name] | |
| puts '' | |
| values = target_options.map do |option| | |
| text_metadata[option].to_s.rjust(width) | |
| end | |
| puts [*values, text_metadata[:name]].join(' ') |
みたいにするとちょっとスッキリするかも
JunichiIto
left a comment
There was a problem hiding this comment.
いくつかコメントしましたが大きな問題ではないのでこれでOKです!🙆♂️
| opt.on('-w') { |v| word = v } | ||
| opt.on('-c') { |v| size = v } | ||
| paths = opt.parse(ARGV) | ||
| column_names = [line, word, size].none? ? %i[line_count word_count size] : { line_count: line, word_count: word, size: size }.select { |_, v| v }.keys |
There was a problem hiding this comment.
ちょっと横に長すぎる気がしますね。改行した方が読みやすいかも。
| column_names = [line, word, size].none? ? %i[line_count word_count size] : { line_count: line, word_count: word, size: size }.select { |_, v| v }.keys | |
| column_names = [line, word, size].none? ? | |
| %i[line_count word_count size] : | |
| { line_count: line, word_count: word, size: size }.select { |_, v| v }.keys |
| end | ||
|
|
||
| def render(statistics, column_names, width) | ||
| filterd_statistics = column_names.map do |column_name| |
There was a problem hiding this comment.
filterd -> filtered ですね。
ただ、filteredだと不要なデータを取り除くイメージです。
https://docs.ruby-lang.org/ja/latest/method/Array/i/filter.html
ここでやってるのは見た目の調整だと思うので、formatted とかの方が良さそうです

レビューお願いいたします